<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>事件循环eventloop | 一枚前端小菜鸟的博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="事件循环eventloop关于javascriptjavascript是一门单线程语言，在最新的HTML5中提出了Web-Worker, 但javascript是单线程这一核心扔未改变。所以一切javascript版的“多线程”都是用单线程模拟出来的，一切javascript多线程都是纸老虎 JS为什么是单线程的最初设计JS是用来在浏览器验证表单操控DOM元素的是一门脚本语言，如果js是多线程的，">
<meta property="og:type" content="article">
<meta property="og:title" content="事件循环eventloop">
<meta property="og:url" content="https://gitee.com/weiyayun1995/weiyayun1995.git/2021/05/25/%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AFeventloop/index.html">
<meta property="og:site_name" content="一枚前端小菜鸟的博客">
<meta property="og:description" content="事件循环eventloop关于javascriptjavascript是一门单线程语言，在最新的HTML5中提出了Web-Worker, 但javascript是单线程这一核心扔未改变。所以一切javascript版的“多线程”都是用单线程模拟出来的，一切javascript多线程都是纸老虎 JS为什么是单线程的最初设计JS是用来在浏览器验证表单操控DOM元素的是一门脚本语言，如果js是多线程的，">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://assets.che300.com/wiki/2021-05-08/16204594577465347.png">
<meta property="article:published_time" content="2021-05-25T08:29:43.000Z">
<meta property="article:modified_time" content="2021-05-25T08:31:12.047Z">
<meta property="article:author" content="yywei">
<meta property="article:tag" content="菜鸟,前端,js,react,vue">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://assets.che300.com/wiki/2021-05-08/16204594577465347.png">
  
    <link rel="alternate" href="/atom.xml" title="一枚前端小菜鸟的博客" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">一枚前端小菜鸟的博客</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">yywei的遇坑记录</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS 订阅"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="搜索"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="搜索"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://gitee.com/weiyayun1995/weiyayun1995.git"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-事件循环eventloop" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2021/05/25/%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AFeventloop/" class="article-date">
  <time class="dt-published" datetime="2021-05-25T08:29:43.000Z" itemprop="datePublished">2021-05-25</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="p-name article-title" itemprop="headline name">
      事件循环eventloop
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h5 id="事件循环eventloop"><a href="#事件循环eventloop" class="headerlink" title="事件循环eventloop"></a>事件循环eventloop</h5><h4 id="关于javascript"><a href="#关于javascript" class="headerlink" title="关于javascript"></a>关于javascript</h4><p>javascript是一门单线程语言，在最新的HTML5中提出了Web-Worker, 但javascript是单线程这一核心扔未改变。所以一切javascript版的“多线程”都是用单线程模拟出来的，一切javascript多线程都是纸老虎</p>
<h4 id="JS为什么是单线程的"><a href="#JS为什么是单线程的" class="headerlink" title="JS为什么是单线程的"></a>JS为什么是单线程的</h4><p>最初设计JS是用来在浏览器验证表单操控DOM元素的是一门脚本语言，如果js是多线程的，那么两个线程同时对一个DOM元素进行了相互冲突的操作，那么浏览器的解析器是无法执行的。</p>
<h4 id="js为什么需要异步"><a href="#js为什么需要异步" class="headerlink" title="js为什么需要异步"></a>js为什么需要异步</h4><p>如果js中不存在异步，只能自上而下执行，如果上一行解析时间很长，那么下面的代码就会被阻塞。 对于用户而言，阻塞就以为着“卡死”，这样就导致了很差的用户体验。比如在进行ajax请求的时候如果没有返回数据后面的代码就没办法执行</p>
<h4 id="js单线程又是如何实现异步的呢"><a href="#js单线程又是如何实现异步的呢" class="headerlink" title="js单线程又是如何实现异步的呢"></a>js单线程又是如何实现异步的呢</h4><p>js中的异步以及多线程都可以理解成为一种“假象”，就拿h5的WebWorker来说，子线程有诸多限制，不能控制DOM，不能修改全局对象等等，通常只用来做计算做数据处理。<br>这些限制并没有违背我们之前的观点，所以说是“假象”。JS异步的执行机制其实就是事件循环（eventloop）,理解了eventloop机制，就理解了js异步的执行机制。</p>
<h4 id="JS的事件循环（eventloop）是怎么运作的"><a href="#JS的事件循环（eventloop）是怎么运作的" class="headerlink" title="JS的事件循环（eventloop）是怎么运作的"></a>JS的事件循环（eventloop）是怎么运作的</h4><p>事件循环、eventloop\运行机制 这三个术语其实说的是同一个东西，</p>
<ol>
<li>首先判断JS是同步还是异步，同步就进入主线程运行，异步就进入event table.</li>
<li>异步任务在event table中注册事件，当满足触发条件后，（触发条件可能是延时也可能是ajax回调），被推入event queue</li>
<li>同步任务进入主线程后一直执行，直到主线程空闲时，才会去event queue中查看是否有可执行的异步任务，如果有就推入主线程中。<br><img src="https://assets.che300.com/wiki/2021-05-08/16204594577465347.png"></li>
<li>那怎么知道主线程执行栈为空啊？js引擎存在monitoring process进程，会持续不断的检查 主线程 执行栈是否为空，一旦为空，就会去event queue那里检查是否有等待被调用的函数<h4 id="宏任务、微任务"><a href="#宏任务、微任务" class="headerlink" title="宏任务、微任务"></a>宏任务、微任务</h4></li>
</ol>
<p><strong>js微任务宏任务执行机制</strong><br>遇到宏任务，先执行宏任务，将宏任务放入eventqueue，然后在执行微任务，将微任务放入eventqueue，<br>这两个queue不是一个queue。当你往外拿的时候先从微任务里拿这个回调函数，然后再从宏任务的queue上拿宏任务的回掉函数。 </p>
<p><strong>宏任务</strong><br>| #                     | 浏览器 | Node   |<br>| ——————— | —— | —— |<br>| script整体代码块      | 是     | 是     |<br>| UI交互事件            | 是     | 是     |<br>| I/O                   | 是     | 是     |<br>| setTimeout            | 是     | 是     |<br>| setInterval           | 是     | 是     |<br>| requestAnimationFrame | 是     | 否     |<br>| setImmediate          | 否     | 是     |<br>| postMessage           | 是     | 没测试 |<br>| MessageChannel        | 是     | 没测试 |<br><strong>微任务</strong><br>| #                | 浏览器 | Node |<br>| —————- | —— | —- |<br>| process.nextTick | 否     | 是   |<br>| promise.then     | 是     | 是   |<br>| MutationObserver | 是     | 否   |<br>| Object.observe   | 是     | 是   |</p>
<h4 id="自己对于同步、异步、宏任务、微任务的理解"><a href="#自己对于同步、异步、宏任务、微任务的理解" class="headerlink" title="自己对于同步、异步、宏任务、微任务的理解"></a>自己对于同步、异步、宏任务、微任务的理解</h4><ol>
<li>先执行代码中的同步任务</li>
<li>同步代码中依次执行微任务、宏任务</li>
<li>再依次执行异步任务</li>
<li>异步任务中依次执行微任务、宏任务</li>
</ol>
<h4 id="async-await的执行顺序"><a href="#async-await的执行顺序" class="headerlink" title="async/await的执行顺序"></a>async/await的执行顺序</h4><p>async表示异步代码块<br>在async中，遇到await会阻塞后面的代码，先执行async外面的同步代码，同步代码执行完，再回到async内部，继续执行await后面的代码。以下面的代码分析</p>
<h4 id="eventloop的几个例子"><a href="#eventloop的几个例子" class="headerlink" title="eventloop的几个例子"></a>eventloop的几个例子</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> data = [];</span><br><span class="line">$.ajax(&#123;</span><br><span class="line">    url:www.javascript.com,</span><br><span class="line">    data:data,</span><br><span class="line">    success:<span class="function">() =&gt;</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;发送成功!&#x27;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">&#x27;代码执行结束&#x27;</span>);</span><br><span class="line"><span class="comment">// 执行顺序如下</span></span><br><span class="line"><span class="number">1.</span> ajax放入event table中，生成回调函数success</span><br><span class="line"><span class="number">2.</span> 执行宏任务<span class="built_in">console</span></span><br><span class="line"><span class="number">3.</span> ajax回调函数注入到event queue中</span><br><span class="line"><span class="number">4.</span> 读取event queue 中的success并执行</span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;2秒到了&#x27;</span>)</span><br><span class="line">&#125;, <span class="number">2000</span>)</span><br><span class="line"><span class="number">1.</span> ajax放入event table中</span><br><span class="line"><span class="number">2.</span> <span class="number">2</span>秒后生成回调函数 <span class="built_in">console</span>.log(<span class="string">&#x27;2秒到了&#x27;</span>) 放入到event queue中</span><br><span class="line"><span class="number">3.</span> 读取event queue中回调函数并执行</span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://gitee.com/weiyayun1995/weiyayun1995.git/2021/05/25/%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AFeventloop/" data-id="ckq7mlsvf000fdgt9hmiefcjr" data-title="事件循环eventloop" class="article-share-link">分享</a>
      
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2021/05/26/%E6%A0%BC%E5%BC%8F%E5%8C%96%E6%97%B6%E9%97%B4%E6%88%B3/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">前一篇</strong>
      <div class="article-nav-title">
        
          格式化时间戳
        
      </div>
    </a>
  
  
    <a href="/2021/05/25/eslint%E4%BB%A3%E7%A0%81%E8%87%AA%E5%8A%A8%E6%A0%BC%E5%BC%8F%E5%8C%96%E9%85%8D%E7%BD%AE/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">后一篇</strong>
      <div class="article-nav-title">eslint代码自动格式化配置</div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    

  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/06/">六月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/05/">五月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/04/">四月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/03/">三月 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2021/06/22/js%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E5%8F%8A%E8%BD%AC%E6%8D%A2/">js数据类型及转换</a>
          </li>
        
          <li>
            <a href="/2021/06/18/react-hook-%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%AE%9E%E8%B7%B5/">react-hook 项目中实践</a>
          </li>
        
          <li>
            <a href="/2021/06/18/%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D/">数字签名</a>
          </li>
        
          <li>
            <a href="/2021/06/18/sendbeacon/">sendbeacon</a>
          </li>
        
          <li>
            <a href="/2021/06/18/js%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%88%A4%E6%96%AD/">js数据类型的判断</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2021 yywei<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/js/jquery-3.4.1.min.js"></script>



  
<script src="/fancybox/jquery.fancybox.min.js"></script>




<script src="/js/script.js"></script>





  </div>
</body>
</html>